package com.demo02_interaction.service;


import com.demo02_interaction.client.UserServiceClient;
import com.demo02_interaction.client.VideoServiceClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Slf4j
public class LikeService {
    //使用RedisTemplate
    private final RedisTemplate<String, String> redisTemplate;
    private final UserServiceClient userServiceClient;
    private final VideoServiceClient videoServiceClient;

    public void likeVideo(Long userId, Long videoId) {
        // 1. 验证用户是否存在
        try {
            Boolean userExists = userServiceClient.checkUserExists(userId);
            if (Boolean.FALSE.equals(userExists)) {
                throw new RuntimeException("用户不存在: " + userId);
            }
        } catch (Exception e) {
            log.error("检查用户存在时发生错误: {}", userId, e);
            throw new RuntimeException("无法验证用户信息");
        }
        
        // 2. 验证视频是否存在
        try {
            Boolean videoExists = videoServiceClient.checkVideoExists(videoId);
            if (Boolean.FALSE.equals(videoExists)) {
                throw new RuntimeException("视频不存在: " + videoId);
            }
        } catch (Exception e) {
            log.error("检查视频存在时发生错误: {}", videoId, e);
            throw new RuntimeException("无法验证视频信息");
        }

        //3.生成Redis key
        String likeKey = "like:video:" + videoId;//存储点赞用户ID集合
        String countKey = "count:video:" + videoId;//存储点赞数量Hash

        //4.判断用户是否已经点赞(SISMEMBER)
        Boolean isMember = redisTemplate.opsForSet().isMember(likeKey, userId.toString());
        if (Boolean.TRUE.equals(isMember)) {
            throw new RuntimeException("用户已经点赞");
        }

        //5.点赞:将用户ID添加到Set集合中，并计数
        redisTemplate.opsForSet().add(likeKey, userId.toString());
        redisTemplate.opsForHash().increment(countKey, "likeCount", 1);
        
        //6.通知视频服务更新点赞计数（异步）
        try {
            videoServiceClient.updateLikeCount(videoId, 1);
        } catch (Exception e) {
            log.error("通知视频服务更新点赞数失败: {}", videoId, e);
            // 这里可以选择重试机制或记录日志，但不应该让点赞操作失败
        }
    }

    public Long getLikeCount(Long videoId) {
        //1.生成Redis key
        String countKey = "count:video:" + videoId;

        //2.获取点赞数量
        Object count = redisTemplate.opsForHash().get(countKey, "likeCount");
        return count == null ? 0L : Long.parseLong(count.toString());
    }
    
    public void unlikeVideo(Long userId, Long videoId) {
        //1.生成Redis key
        String likeKey = "like:video:" + videoId;//存储点赞用户ID集合
        String countKey = "count:video:" + videoId;//存储点赞数量Hash

        //2.判断用户是否已经点赞(SISMEMBER)
        Boolean isMember = redisTemplate.opsForSet().isMember(likeKey, userId.toString());
        if (Boolean.FALSE.equals(isMember)) {
            throw new RuntimeException("用户未点赞");
        }

        //3.取消点赞:将用户ID从Set集合中移除，并减少计数
        redisTemplate.opsForSet().remove(likeKey, userId.toString());
        redisTemplate.opsForHash().increment(countKey, "likeCount", -1);
        
        //4.通知视频服务更新点赞计数（异步）
        try {
            videoServiceClient.updateLikeCount(videoId, -1);
        } catch (Exception e) {
            log.error("通知视频服务更新点赞数失败: {}", videoId, e);
        }
    }
}
